package com.tengju.bff.interfaces.manage.crm.dashborad.facade;

import com.tengju.bff.interfaces.manage.crm.dashborad.vo.SecMarketAnalysisVO;
import com.tengju.bff.interfaces.shared.*;
import com.tengju.data.domain.model.clickhouse.CrmSecAnalysisM;
import com.tengju.data.domain.model.clickhouse.CrmSecAnalysisMRepository;
import com.tengju.data.domain.model.user.StarLevelEnum;
import com.tengju.data.domain.shared.DateUtil;
import com.tengju.data.domain.shared.Month;
import com.tengju.user.domain.model.user.UserIdCode;
import com.tengju.user.domain.model.user.UserInfo;
import com.tengju.user.domain.model.user.UserInfoRepository;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * @author chenhang
 * @Date 2021/3/6
 */
@Service
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class SecMarketAnalysisFacade {

    private final CrmSecAnalysisMRepository crmSecAnalysisMRepository;
    private final UserInfoRepository userInfoRepository;

    public SecMarketAnalysisVO secMarketAnalysis(Long clubId) {
        LocalDateTime now = LocalDateTime.now();
        String ymtd = DateUtil.getLastMonthDay(now.minusMonths(1));
        String td = DateUtil.formatVisitDate(now);
        String ytd = DateUtil.formatVisitDate(now.minusDays(1));
        Month curMonth = new Month(now.toLocalDate());
        List<CrmSecAnalysisM> sqlResult = crmSecAnalysisMRepository
                .listSecAnalysis(clubId, td, ytd, ymtd, curMonth);
        if (CollectionUtils.isEmpty(sqlResult)) {
            return null;
        }
        //确定当月数据，如果当天数据未产出，取当月最后一天有数据的日期
        String md = sqlResult.stream()
                .map(CrmSecAnalysisM::getVisitDate)
                .max(Comparator.comparing(v -> v))
                .orElseGet(() -> "");

        if (StringUtils.isEmpty(md) && curMonth.sameMonth(LocalDate.parse(md))) {
            return null;
        }
        //计算当月、上月、今日、昨日数据
        Map<Long, CrmSecAnalysisM> mMap = new HashMap<>();
        Map<Long, CrmSecAnalysisM> ymMap = new HashMap<>();
        Map<Long, CrmSecAnalysisM> tdMap = new HashMap<>();
        Map<Long, CrmSecAnalysisM> ytdMap = new HashMap<>();
        List<com.tengju.user.domain.model.user.UserIdCode> queryIdCode = new ArrayList<>();
        BigDecimal mMoneyOut = BigDecimal.ZERO;
        BigDecimal ymMoneyOut = BigDecimal.ZERO;
        BigDecimal tdMoneyOut = BigDecimal.ZERO;
        BigDecimal ytdMoneyOut = BigDecimal.ZERO;
        for (CrmSecAnalysisM crmSecAnalysisM : sqlResult) {
            //上月数据
            if (ymtd.equals(crmSecAnalysisM.getVisitDate())) {
                ymMoneyOut = ymMoneyOut.add(crmSecAnalysisM.getMMoneyOut());
                ymMap.put(crmSecAnalysisM.getIdCode().getValue(), crmSecAnalysisM);
            }
            //当天数据
            if (td.equals(crmSecAnalysisM.getVisitDate())) {
                tdMoneyOut = tdMoneyOut.add(crmSecAnalysisM.getTdMoneyOut());
                tdMap.put(crmSecAnalysisM.getIdCode().getValue(), crmSecAnalysisM);
            }
            //昨日数据
            if (ytd.equals(crmSecAnalysisM.getVisitDate())) {
                ytdMoneyOut = ytdMoneyOut.add(crmSecAnalysisM.getTdMoneyOut());
                ytdMap.put(crmSecAnalysisM.getIdCode().getValue(), crmSecAnalysisM);
            }
            //当月数据
            if (md.equals(crmSecAnalysisM.getVisitDate())) {
                mMoneyOut = mMoneyOut.add(crmSecAnalysisM.getMMoneyOut());
                mMap.put(crmSecAnalysisM.getIdCode().getValue(), crmSecAnalysisM);
            }
        }
        queryIdCode = mMap.values().stream()
                .map(v -> UserIdCode.of(v.getIdCode().getValue()))
                .collect(Collectors.toList());

        List<UserInfo> userInfos = userInfoRepository.batchGetUserInfo(queryIdCode);
        Map<Long, UserInfo> userInfoMap = userInfos.stream()
                .collect(Collectors.toMap(k -> k.getIdCode().getValue(), v -> v, (v1, v2) -> v1));

        //组装数据
        SecMarketAnalysisVO result = new SecMarketAnalysisVO();
        List<KVVO> header = List.of(
                KVVO.of(String.format("本月业绩(%s)", DateUtil.formatLocalDateTime("yyyy.MM",now)), mMoneyOut),
                KVVO.of(String.format("上月业绩(%s)", DateUtil.formatLocalDateTime("yyyy.MM",now.minusMonths(1))), ymMoneyOut),
                KVVO.of(String.format("今日业绩(%s)", DateUtil.formatLocalDateTime("MM.dd",now)), tdMoneyOut),
                KVVO.of(String.format("昨日业绩(%s)", DateUtil.formatLocalDateTime("MM.dd",now.minusDays(1))), ytdMoneyOut));
        result.setHeader(header);
        TableVO table = new TableVO();
        result.setTable(table);
        List<ColumnVO> columns = List.of(
                ColumnVO.of("showName", "用户", false),
                ColumnVO.of("rank", "本月大盘排名", false),
                ColumnVO.of("mMoneyOut", "本月业绩", true),
                ColumnVO.of("ymMoneyOut", "上月业绩", true),
                ColumnVO.of("tdMoneyOut", "今日业绩", true),
                ColumnVO.of("ytdMoneyOut", "昨日业绩", true));
        List<Map<String, Object>> rows = buildSecAnalysisRecords(mMap,tdMap,ymMap,ytdMap,userInfoMap);
        table.setHeader(columns);
        table.setRecords(rows);
        return result;
    }

    private List<Map<String, Object>> buildSecAnalysisRecords(Map<Long, CrmSecAnalysisM> mMap, Map<Long, CrmSecAnalysisM> tdMap, Map<Long, CrmSecAnalysisM> ymMap, Map<Long, CrmSecAnalysisM> ytdMap, Map<Long, UserInfo> userInfoMap) {
        List<Map<String, Object>> rows = new ArrayList<>();
        Set<Map.Entry<Long, CrmSecAnalysisM>> entries = mMap.entrySet();
        for (Map.Entry<Long, CrmSecAnalysisM> entry : entries) {
            Map<String, Object> row = new HashMap<>();
            Long idCodeValue = entry.getKey();
            CrmSecAnalysisM mCrmSecAnalysisM = entry.getValue();
            CrmSecAnalysisM ymCrmSecAnalysisM = ymMap.get(idCodeValue);
            CrmSecAnalysisM ytdCrmSecAnalysisM = ytdMap.get(idCodeValue);
            CrmSecAnalysisM tdCrmSecAnalysisM = tdMap.get(idCodeValue);
            UserInfo userInfo = userInfoMap.get(idCodeValue);
            StarLevelEnum starLevelEnum = StarLevelEnum.parseByStarLevel(userInfo.getStarLevel());
            String showName = userInfo.getNickName();
            if (StringUtils.isEmpty(showName)) {
                showName = new MobileVO(userInfo.getWholePhoneNumber()).toString();
            }
            row.put("showName", showName + " " + starLevelEnum.getDesc());
            if (ytdCrmSecAnalysisM != null) {
                row.put("ytdMoneyOut", new AmountVO(AmountType.THOUSAND, ytdCrmSecAnalysisM.getTdMoneyOut()));
            } else {
                row.put("ytdMoneyOut", new AmountVO(AmountType.THOUSAND, BigDecimal.ZERO));
            }
            if (ymCrmSecAnalysisM != null) {
                row.put("ymMoneyOut", new AmountVO(AmountType.THOUSAND, ymCrmSecAnalysisM.getMMoneyOut()));
                row.put("rank", RankVO.of(mCrmSecAnalysisM.getRank(), ymCrmSecAnalysisM.getRank()));
            } else {
                row.put("ymMoneyOut", new AmountVO(AmountType.THOUSAND, BigDecimal.ZERO));
                row.put("rank", RankVO.of(mCrmSecAnalysisM.getRank(), null));
            }
            row.put("tdMoneyOut", new AmountVO(AmountType.THOUSAND, tdCrmSecAnalysisM == null ? BigDecimal.ZERO : tdCrmSecAnalysisM.getTdMoneyOut()));
            row.put("mMoneyOut", new AmountVO(AmountType.THOUSAND, mCrmSecAnalysisM.getMMoneyOut()));
            row.put("idCode",mCrmSecAnalysisM.getIdCode().getValue());
            rows.add(row);
        }
        return rows;
    }


    public static void main(String[] args) {
        new SecMarketAnalysisFacade(null,null).run();
    }

    public void run() {
        LocalDateTime now = LocalDateTime.now();
        String ytd = DateUtil.formatVisitDate(now.minusDays(1));
        System.out.println(ytd);

    }
}
